home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume91 / utilitys / makemenu / part01 / makemenu.c < prev    next >
C/C++ Source or Header  |  1991-03-04  |  15KB  |  520 lines

  1. /* MakeMenu V1.0 (14-oct-90) - by Hans Jansen
  2.  *
  3.  * This program will generate C source to build Intuition menus, from
  4.  * a simple description file. See MakeMenu.Doc for details on usage.
  5.  *
  6.  */
  7.  
  8. #define  DISABLE      0
  9. #define  DEFAULT      1
  10. #define  ENABLE          1
  11. #define  TOGGLE          2
  12. #define  CHECK          4
  13. #define  SELECT          8
  14.  
  15. #define  CHAR_WIDTH      8
  16.  
  17. #include <intuition/intuition.h>
  18. #include <stdio.h>
  19.  
  20. #define NO_ERROR      0
  21. #define ERROR_NO_COMMA      1
  22. #define ERROR_BAD_TEXT      2
  23. #define ERROR_NO_MENU      3
  24. #define ERROR_NO_ITEM      4
  25. #define ERROR_NO_DATA      5
  26. #define ERROR_BAD_NUMBER  6
  27. #define ERROR_BAD_COMMAND 7
  28. #define MAX_LINE    132
  29.  
  30. char cline[MAX_LINE];            /* input line            */
  31. char RecBuf[BUFSIZ];            /* input buffer            */
  32. char *ifname, *ofname;            /* File name pointers        */
  33. FILE *ofile;                /* output file handle        */
  34. int  EndOfFile;                /* true = end of file        */
  35. int  lcnt;                /* current input line count    */
  36.  
  37. struct IntuiText *CText;        /* Current Text Item pointer    */
  38. struct IntuiText *AllText;        /* All text items        */
  39. struct MenuItem  *CItem;        /* Current Menu Item        */
  40. struct MenuItem  *CSItem;        /* Current Sub Menu Item    */
  41. struct Menu      *CMenu, *AllMenu;    /* Menu pointers        */
  42.  
  43. main (argc, argv)
  44.   int   argc;                /*number of arguments        */
  45.   char  *argv[];            /*array of ptrs to arg strings    */
  46.  
  47. {
  48.   FILE    *ifile;                /* input File pointer        */
  49.   int    i, j;
  50.   int    result, error;
  51.   char    *Scan();
  52.   int    GetLine();
  53.   char    *cptr;
  54.   char  etype[5];
  55.  
  56. /* get the file names and open the files  */
  57. /* initialize input buffers and variables */
  58.  
  59.   AllText = NULL;
  60.   CText   = NULL;
  61.   CMenu   = NULL;
  62.   CItem   = NULL;
  63.   CSItem  = NULL;
  64.   AllMenu = NULL;
  65.   result  = NO_ERROR;
  66.   error   = 0;
  67.   lcnt    = 0;
  68.  
  69.   if (argc != 3)
  70.       printf ("usage: MakeMenu <inputfile> <outputfile>\n");
  71.  
  72.   for (ifname = NULL, i=1; i<argc && ifname == NULL; i++)
  73.     if ( *argv[i] != '-') ifname = argv[i];
  74.  
  75.   for (ofname = NULL, i=i; i<argc && ofname == NULL; i++)
  76.     if ( *argv[i] != '-') ofname = argv[i];
  77.  
  78.   EndOfFile = FALSE; /* no end of file  */
  79.   ifile      = fopen (ifname, "r");  /* open file for reading */
  80.   if (ifile == NULL) {
  81.     printf (" Cannot open file %s for input!\n", ifname);
  82.     exit (10);
  83.   };
  84.  
  85.   while ((j = GetLine (ifile, cline, sizeof (cline))) > 0) {
  86.     cptr = &cline[0];
  87.     for (i = 0; i < sizeof (etype) -1; i++)
  88.       etype[i] = toupper (*(cptr + i));
  89.     etype[i] = '\0';
  90.     cptr = Scan (cptr, ',', TRUE);
  91.     if (strcmp ("MENU", etype) == 0)
  92.       result = Process_Menu (cptr);        /* do a Menu */
  93.     else if (strcmp ("ITEM", etype) == 0)
  94.       result = Process_Item (cptr, 0);        /* do an Item */
  95.     else if (strcmp ("SUBI", etype) == 0)
  96.       result = Process_Item (cptr, 1);        /* do a SubItem */
  97.     else
  98.     result = ERROR_BAD_COMMAND;
  99.     if (result != NO_ERROR) {
  100.       error++;
  101.       printf (" Line %d has syntax error:%s\n", lcnt, cline);
  102.     };
  103.   };
  104.   fclose (ifile);
  105.   if (error == 0) Do_Output ();
  106. }
  107.  
  108. char *Scan (ptr, c, control)
  109.   char *ptr;
  110.   char c;
  111.   int control;
  112.  
  113. {
  114.   while (*ptr != NULL && ((control && *ptr != c) || (! control && *ptr == c)))
  115.      ptr++;
  116.   return (ptr);  /* return the new pointer */
  117. }
  118.  
  119. GetLine (fptr, line, lsize)    /* get a line from buffer    */
  120.   FILE *fptr;            /* pointer to file to read from */
  121.   char line[];            /* destination of characters    */
  122.   int  lsize;            /* maximum size for destination    */
  123.  
  124. {
  125.     lcnt++;         /* bump line count */
  126.  
  127.     if (fgets (line, lsize, fptr) == NULL) {
  128.        EndOfFile = TRUE;
  129.        return (0);
  130.     }
  131.     else {
  132.        line[strlen (line) - 1] = '\0';        /* discard newline character */
  133.        return (strlen (line));
  134.     }
  135. }
  136.  
  137. int Process_Menu (ptr)
  138.   char *ptr;
  139.   
  140. {
  141.   char *tptr;
  142.   int len;
  143.   struct Menu *last;
  144.  
  145.   if (AllMenu == NULL) {    /* first menu item */
  146.     AllMenu = (struct Menu *) malloc (sizeof (struct Menu));
  147.     CMenu = AllMenu;        /* Set current pointer */
  148.   }
  149.   else {            /* add new one to list */
  150.     last = CMenu;
  151.     CMenu = (struct Menu *) malloc (sizeof(struct Menu));
  152.     last->NextMenu = CMenu;
  153.   };
  154.  
  155. /* Build Menu structure */
  156.  
  157.   if (*ptr != ',') return (ERROR_NO_COMMA);
  158.   ptr++;
  159.  
  160. /* process disable-flag, if any */
  161.  
  162.   if (*ptr == 'D' || *ptr == 'd')
  163.       CMenu->Flags = DISABLE;
  164.   else
  165.       CMenu->Flags = ENABLE;
  166.   ptr = Scan (ptr, ',', TRUE);
  167.   if (*ptr != ',') return (ERROR_NO_COMMA);
  168.   ptr++;
  169.  
  170.   tptr = Scan (ptr, '\0', TRUE); /* find end of string */
  171.   len  = tptr-ptr;
  172.   CMenu->MenuName = (BYTE *) malloc (len+1);
  173.   strcpy (CMenu->MenuName, ptr);
  174.   CMenu->NextMenu = NULL;
  175.   CMenu->FirstItem = NULL;
  176.   CItem = NULL;
  177.   CMenu->Width = len + 3 ;
  178.   return (NO_ERROR);
  179. }
  180.  
  181. int Process_Item (ptr, type)
  182.   char *ptr;
  183.   int type;    /* 0 = Item, 1 = SubItem */
  184.  
  185. {
  186.   struct IntuiText *Process_Text();
  187.   struct MenuItem  *ThisItem;
  188.   struct MenuItem  *lastI;
  189.   struct MenuItem  *lastSI;
  190.  
  191.   if (CMenu == NULL)               return(ERROR_NO_MENU);
  192.   if (type  == 1 && CItem == NULL) return(ERROR_NO_ITEM);
  193.   if (*ptr  != ',')                return(ERROR_NO_COMMA);
  194.  
  195.   if (type  == 0) {            /* Build a MenuItem */
  196.     lastI  = CItem;
  197.     CSItem = NULL;  /* clear current Sub Item Flag */
  198.     CItem  = (struct MenuItem *) malloc (sizeof (struct MenuItem));
  199.  
  200.     if (lastI == NULL)            /* First Item for Menu */
  201.       CMenu->FirstItem = CItem;        /* link it to the menu */
  202.     else
  203.       lastI->NextItem = CItem;        /* link it to the item list */
  204.     ThisItem = CItem;            /* build it */
  205.   }
  206.   else {                /* Build a SubItem */
  207.     lastSI = CSItem;
  208.     CSItem = (struct MenuItem *) malloc (sizeof (struct MenuItem));
  209.     if (lastSI == NULL)            /* First Sub Item for Menu Item */
  210.       CItem->SubItem = CSItem;        /* link in the sub items */
  211.     else
  212.       lastSI->NextItem = CSItem;
  213.     ThisItem = CSItem;
  214.   };
  215.  
  216. /* Process flags, name, select and command */
  217.  
  218.   ptr++;
  219.   ThisItem->Flags = ENABLE;
  220.   while (*ptr != ',') {
  221.       if (*ptr == 'D' || *ptr == 'd') ThisItem->Flags &= ~ENABLE;
  222.       else if (*ptr == 'T' || *ptr == 't') ThisItem->Flags |= TOGGLE;
  223.       else if (*ptr == 'C' || *ptr == 'c') ThisItem->Flags |= CHECK;
  224.       else if (*ptr == 'S' || *ptr == 's') ThisItem->Flags |= SELECT;
  225.       ptr++;
  226.   }
  227.  
  228.   ptr++;
  229.    
  230.   ThisItem->ItemFill = (APTR) Process_Text (ptr);
  231.   if (ThisItem->ItemFill == NULL) return (ERROR_BAD_TEXT);
  232.  
  233.   ptr = Scan (ptr, ',', TRUE); /* find next comma */
  234.   if (*ptr != ',') return (ERROR_NO_COMMA);
  235.   ptr++;
  236.  
  237. /* Select name? */
  238.  
  239.   ThisItem->SelectFill = (APTR) Process_Text (ptr);
  240.  
  241.   ptr = Scan (ptr, ',', TRUE); /* find next comma */
  242.   if (*ptr != ',') return (ERROR_NO_COMMA);
  243.   ptr++;
  244.  
  245. /* Command ? */
  246.   ThisItem->NextItem      = NULL;
  247.   ThisItem->SubItem       = NULL;
  248.   ThisItem->Command       = *ptr;
  249.   ThisItem->MutualExclude = 0L;
  250.   return (NO_ERROR);
  251. }
  252.  
  253. struct IntuiText *Process_Text (ptr)
  254.   char *ptr;
  255. {
  256.   
  257.   struct IntuiText *dptr, *lasText;
  258.   char *tptr;
  259.  
  260.   if (*ptr == ',') return (NULL);
  261.  
  262.   lasText = AllText;
  263.   while (lasText != NULL) {     /* search end of saved-texts list */
  264.     CText = lasText;
  265.     lasText = lasText->NextText;
  266.   };
  267.   lasText = CText;
  268.   CText = (struct IntuiText *) malloc (sizeof (struct IntuiText));
  269.   CText->NextText = NULL;
  270.   if( AllText == NULL )
  271.     AllText = CText;
  272.   else
  273.     lasText->NextText = CText;
  274.  
  275.   tptr = Scan (ptr, ',', TRUE);
  276.   CText->IText = (UBYTE *) malloc (tptr-ptr+1);
  277.   strncpy (CText->IText, ptr, tptr-ptr);
  278.   if (CMenu->Width <= tptr-ptr) CMenu->Width = tptr-ptr;
  279.  
  280. /* check for duplicate, eliminate this one if duplicate */
  281.   
  282.   dptr = AllText;
  283.   while (dptr != CText) {
  284.     if (strcmp (dptr->IText, CText->IText) == 0 ) {
  285.       free ((char *) (CText->IText));
  286.       free ((char *) CText);
  287.       CText = dptr;
  288.       lasText->NextText = NULL;
  289.     }
  290.     else dptr = dptr->NextText;
  291.   }
  292.   return (CText);
  293. }
  294.  
  295. Do_Output()
  296.  
  297. {
  298.   char nxt, quote, Flag[10];
  299.   char Mptr[14];
  300.   int Menu, Item, left, top, width, height;
  301.   int stop;
  302.   char rest[60];
  303.  
  304.   ofile = fopen (ofname, "w");  /* open file for writing */
  305.   if (ofile == NULL) {
  306.     printf (" Cannot open file %s for output!\n", ofname);
  307.     exit (10);
  308.   }
  309.  
  310. /* Output the IntuiText structure first */
  311.  
  312.   quote = '"';
  313.   fprintf (ofile, "/*****************************************/\n");
  314.   fprintf (ofile, "/*      This code was generated by:      */\n");
  315.   fprintf (ofile, "/* MakeMenu V1.0 (Hans Jansen  7-oct-90) */\n");
  316.   fprintf (ofile, "/*****************************************/\n");
  317.   fprintf (ofile, "#include <exec/types.h>\n");
  318.   fprintf (ofile, "#include <intuition/intuition.h>\n");
  319.  
  320.   CText = AllText;
  321.   if (AllText != NULL) {
  322.     fprintf (ofile, "\nstruct IntuiText IText[] =\n");
  323.     fprintf (ofile, "  {\n");
  324.   };
  325.  
  326.   while (CText != NULL) {         /* for all text to output */
  327.     if (CText->NextText == NULL) nxt = ' ';
  328.     else nxt = ',';
  329.     fprintf (ofile, "    { 0, 1, JAM2, CHECKWIDTH, 0, NULL, %c%s%c, NULL }%c\n",
  330.       quote, CText->IText, quote, nxt);
  331.     CText = CText->NextText;
  332.   };
  333.  
  334.   if (AllText != NULL) fprintf (ofile,"  };\n\n");
  335.  
  336.   CMenu = AllMenu;
  337.   Menu = 0;
  338.   left = 0;
  339.   Item = 0;
  340.   height = 10;
  341.  
  342.   while (CMenu != NULL) {         /* first output the subitems, if any */
  343.     Item = 0;
  344.     CItem = CMenu->FirstItem;
  345.     while (CItem != NULL) {
  346.       CSItem = CItem->SubItem;
  347.       if (CSItem != NULL) Do_Out_Sub (Menu,Item);
  348.       Item++;
  349.       CItem = CItem->NextItem;
  350.     };
  351.     Menu++;
  352.     CMenu = CMenu->NextMenu;
  353.   }
  354.  
  355.   CMenu = AllMenu;
  356.   Menu = 0;
  357.   left = 0;
  358.   Item = 0;
  359.   height = 10;
  360.  
  361.   while (CMenu != NULL) {           /* now output the items */
  362.     Item = 0;
  363.     CItem = CMenu->FirstItem;
  364.     CSItem = CItem->SubItem;
  365.     top  = 0;
  366.     fprintf (ofile, "struct MenuItem M%d[] = \n",Menu);
  367.     fprintf (ofile, "  {\n");
  368.     top  = 0;
  369.     width =  CMenu->Width * CHAR_WIDTH;
  370.  
  371.     while (CItem != NULL) {
  372.       Item++;
  373.       CSItem = CItem->SubItem;
  374.  
  375.       if (CItem->NextItem == NULL) fprintf (ofile, "    {NULL, ");
  376.       else fprintf (ofile, "    {&M%d[%2d], ", Menu, Item);
  377.       fprintf (ofile, "%3d, %3d, %3d+CHECKWIDTH, %3d,\n",
  378.             left, top, width, height);
  379.       fprintf (ofile, "      ITEMTEXT|HIGHCOMP");
  380.       if ((CItem->Flags & ENABLE) == ENABLE) fprintf (ofile, "|ITEMENABLED");
  381.       if ((CItem->Flags & TOGGLE) == TOGGLE) fprintf (ofile, "|MENUTOGGLE");
  382.       if ((CItem->Flags & CHECK)  == CHECK)  fprintf (ofile, "|CHECKIT");
  383.       if ((CItem->Flags & SELECT) == SELECT) fprintf (ofile, "|CHECKED");
  384.       if (CItem->Command != NULL && CItem->Command != ' ')
  385.           fprintf (ofile, "|COMMSEQ");
  386.       fprintf (ofile, ",\n      0, (APTR)&IText[%2d], ",
  387.             Index(CItem->ItemFill));
  388.       if (CItem->SelectFill == NULL) fprintf (ofile, "NULL, ");
  389.       else fprintf (ofile, "(APTR)&IText[%2d], ", Index(CItem->SelectFill));
  390.       if (CItem->Command == NULL || CItem->Command == ' ')
  391.           fprintf (ofile, "NULL, ");
  392.       else fprintf (ofile, "'%c', ", CItem->Command);
  393.       if (CSItem == NULL) fprintf (ofile, "NULL, MENUNULL}");
  394.       else fprintf (ofile, "&M%dI%d[0], MENUNULL}", Menu, (Item-1));
  395.       if (CItem->NextItem == NULL) fprintf (ofile, "\n");
  396.       else fprintf (ofile, ",\n");
  397.  
  398.       CItem = CItem->NextItem;
  399.       top   = top + height;
  400.     };
  401.     fprintf (ofile, "  };\n\n");
  402.     CMenu = CMenu->NextMenu;
  403.     Menu++;
  404.   };
  405.  
  406.   CMenu = AllMenu;
  407.   fprintf (ofile, "struct Menu TheMenu[] =\n");
  408.   fprintf (ofile, "  {\n");
  409.   left = 0;
  410.   top  = 0;
  411.   Menu = 0;
  412.   
  413.   while (CMenu != NULL) {           /* finally, the menus themselves */
  414.     Menu++;
  415.     width = CMenu->Width * CHAR_WIDTH;
  416.     if (CMenu->NextMenu == NULL) {    /* the NextMenu pointer */
  417.       sprintf (Mptr, "NULL       ");
  418.       nxt = ' ';
  419.     }
  420.     else {
  421.       sprintf (Mptr, "&TheMenu[%2d]", Menu);
  422.       nxt = ',';
  423.     };
  424.     (void) strncpy (rest, "                               ", 25);
  425.     stop = CMenu->Width - strlen (CMenu->MenuName);    /* the name string */
  426.     if (stop <= 0)
  427.       (void) strncpy (rest, CMenu->MenuName, 25);
  428.     else {
  429.       stop = stop / 2;
  430.       (void) strncpy (&rest[stop], CMenu->MenuName, 25-stop);
  431.       (void) strncat (rest, "                         ", 25);
  432.     };
  433.  
  434.     quote = '"';
  435.     height = 10;
  436.     fprintf (ofile, "    {%12s, %3d, %3d, %3d+CHECKWIDTH, %3d,\n",
  437.             Mptr, left, top, width, height);
  438.     if ((CMenu->Flags & ENABLE) == ENABLE)
  439.         fprintf (ofile, "MENUENABLED");
  440.     else
  441.         fprintf (ofile, "0");
  442.     fprintf (ofile, ",%c%s%c, &M%d[0]}%c\n",
  443.             quote, rest, quote, (Menu-1), nxt);
  444.     left = left + width + 4*CHAR_WIDTH;
  445.     CMenu = CMenu->NextMenu;
  446.   };
  447.   fprintf (ofile, "  };\n\n");
  448.   fprintf (ofile, "struct Menu *MyMenu = &TheMenu[0];\n\n");
  449.  
  450.   fprintf (ofile, "/*****************************************/\n");
  451.   fprintf (ofile, "/*         End of generated code         */\n");
  452.   fprintf (ofile, "/*****************************************/\n");
  453.  
  454.   fclose (ofile);
  455. }
  456.  
  457. int Index (ptr)   /* Find the position index */
  458.   struct IntuiText *ptr;
  459.  {
  460.   int idx;
  461.  
  462.   idx = 0;
  463.   CText = AllText;
  464.  
  465.   while (CText != NULL && ptr != CText) {
  466.     idx++;
  467.     CText = CText->NextText;
  468.   };
  469.   return (idx);
  470. }
  471.  
  472. Do_Out_Sub (Menu, Item)           /* output an item's SubItems */
  473.   int Menu, Item;
  474.   int SItem;
  475.   int stop, width, sleft;
  476.   int top, height;
  477.   char Mptr[14];
  478.   char rest[60];
  479.   char nxt, Flag[10];
  480.  
  481.   SItem = 0;
  482.   top = 0;
  483.   height = 10;
  484.   fprintf (ofile, "struct MenuItem M%dI%d[] = \n", Menu, Item);
  485.   fprintf (ofile, "  {\n");
  486.   width = CMenu->Width*CHAR_WIDTH;
  487.   SItem = 0;
  488.   while (CSItem != NULL) {
  489.     SItem++;
  490.     sleft =  (width * 7) / 10;
  491.     stop  =  top + 2;
  492.     if (CSItem->NextItem == NULL) fprintf (ofile, "    {NULL, ");
  493.     else fprintf (ofile, "    {&M%dI%d[%2d], ", Menu, Item, SItem);
  494.     fprintf (ofile, "%3d, %3d, %3d+CHECKWIDTH, %3d,\n",
  495.             sleft, stop, width, height);
  496.     fprintf (ofile, "      ITEMTEXT|HIGHCOMP");
  497.     if ((CSItem->Flags & ENABLE) == ENABLE) fprintf (ofile, "|ITEMENABLED");
  498.     if ((CSItem->Flags & TOGGLE) == TOGGLE) fprintf (ofile, "|MENUTOGGLE");
  499.     if ((CSItem->Flags & CHECK)  == CHECK)  fprintf (ofile, "|CHECKIT");
  500.     if ((CSItem->Flags & SELECT) == SELECT) fprintf (ofile, "|CHECKED");
  501.     if (CSItem->Command != NULL && CSItem->Command != ' ')
  502.         fprintf (ofile, "|COMMSEQ");
  503.     fprintf (ofile, ",\n      0, (APTR)&IText[%2d], ",
  504.             Index(CSItem->ItemFill));
  505.     if (CSItem->SelectFill == NULL) fprintf (ofile, "NULL, ");
  506.     else fprintf (ofile, "(APTR)&IText[%2d], ", Index(CSItem->SelectFill));
  507.     if (CSItem->Command == NULL || CSItem->Command == ' ')
  508.         fprintf (ofile, "NULL, ");
  509.     else fprintf (ofile, "'%c', ", CSItem->Command);
  510.     fprintf (ofile, "NULL, MENUNULL}");
  511.     if (CSItem->NextItem == NULL) fprintf (ofile, "\n");
  512.     else fprintf (ofile, ",\n");
  513.  
  514.     CSItem = CSItem->NextItem;
  515.     top = top + height;
  516.   };
  517.   fprintf (ofile,"  };\n\n");
  518. }
  519.